
import java.util.Collection;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

public enum UniManager {
	// provide singleton access to the manager
	instance;

	private static Set<Course> courses = new HashSet<Course>();
	
	public String getStudentsForCourse(String courseNumber) {
		if(courseNumber == null || courseNumber.isEmpty()) {
			throw new IllegalArgumentException("Parameter 'courseNumber' is not valid!");
		}
		
		Course course = getCourseById(courseNumber);
		Iterable<Student> students = course.getRegisteredStudents();
		
		StudentStringTransformer transformer = new StudentStringTransformer();
		return transformer.transform(students);
	}
	
	public Collection<Course> getAllCourses() {
		Collection<Course> courses = new HashSet<Course>();
		for(Course c : UniManager.courses) {
			courses.add(c);
		}
		return courses;
	}
	
	public String getAllCoursesAsString() {
		CourseStringTransformer transformer = new CourseStringTransformer();
		return transformer.transform(courses);
	}
	
	public int getCourseListSize() {
		return courses.size();
	}
	
	private Course getCourseById(String id) {
		for(Course course : courses) {
			if(course.getCourseID().equals(id)) {
				return course;
			}
		}
		return null;
	}
	
	public void addCourse(Course c) {
		if(c == null) {
			throw new IllegalArgumentException("parameter 'c' can not be null!");
		}
		courses.add(c);
	}

	
	/**
	 * this methods unregisters a student from a course.
	 * 
	 * @param c
	 * @param s
	 * @throws Exception when the unregister-period is over or when the student is not registered for this course
	 */
	public void unregisterStudent(Course c, Student s) throws Exception{
		Date now = new Date();
		
		// we do not need to check for registerStart here
		// as there can not be any students in the course
		// before this date anyway.
		
		if(c.getUnregisterEnd().before(now))
			throw new Exception("Unregister-period is over! (Ended: "+c.getUnregisterEnd()+")");
		
		if(!c.getRegisteredStudents().remove(s))
			throw new Exception("Student "+s+" is not registered for this course!");
		
	}


	/**
	 * register a student to a course
	 * 
	 * @param c
	 * @param s
	 * @throws Exception when the student already exists or the register-period is already over or did not start yet
	 */
	public void registerStudent(Course c, Student s) throws Exception{
		Date now = new Date();
		
		if(c.getRegisterStart().after(now) || c.getRegisterEnd().before(now))
			throw new Exception("Not able to register. Only from " + c.getRegisterStart() + " to " + c.getRegisterEnd());
		
		if(c.getRegisteredStudents().contains(s))
			throw new Exception("Student " + s + " already registered!");
		
		c.getRegisteredStudents().add(s);
	}
}